home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / presto / prest_04.lha / src / spinlock_impl.h < prev    next >
C/C++ Source or Header  |  1989-06-06  |  2KB  |  86 lines

  1.  
  2. // Spinlock inline implementations
  3. // Must follow defs for threads, but precede everything else.
  4. //
  5. #if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
  6.  
  7. /*
  8.  * Optimized version of S_LOCK to only make the procedure call
  9.  * if the lock is held.  Would really like to use S_LOCK here,
  10.  * but (potentially) inline functions can't handle loops.
  11.  */
  12.  
  13. SPINLOCK_INLINE 
  14. void
  15. Spinlock::lock()
  16. {
  17. #ifdef    ns32000
  18.     char    *lock_alm = &_alm_base[ALM_HASH(sl_lock)]; 
  19. #endif
  20.  
  21.     //
  22.     // Must mark ourselves in the lock even before we acquire it.
  23.     // Otherwise, we could hold the lock and be preempted.  If we
  24.     // were holding the lock on something that the preemption code
  25.     // needed (or someone else, in order to ensure we run), we would
  26.     // deadlock.  Must make lock acquisition and thread in spin cs
  27.     // marking atomic.
  28.     //
  29.  
  30. #ifndef NO_PREEMPT
  31.     thisthread->holdingspinlock();
  32. #endif  NO_PREEMPT
  33.  
  34. #ifdef ns32000
  35.     if (sl_lock == L_LOCKED)        // u lose
  36.         (void)s_lock(&sl_lock);
  37.     else if (*lock_alm & ALM_LOCKED)    // u lose
  38.         (void)s_lock(&sl_lock);
  39.     else if (sl_lock == L_LOCKED) {        // u lose (race condition)
  40.         *lock_alm = ALM_UNLOCKED;
  41.         (void)s_lock(&sl_lock);
  42.     } else    {                // u win
  43.         sl_lock = L_LOCKED;
  44.         *lock_alm = ALM_UNLOCKED;
  45.     }
  46. #else
  47.     //
  48.     // No ALM's in Symmetry.  We use S_LOCK() and to avoid
  49.     // another out-of-line call.  Since C++ doesn't understand
  50.     // asm-functions, must use "CC +hasmdefs.h".
  51.     //
  52.     // On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
  53.     // Should probably be inline.
  54.     //
  55.     (void) S_LOCK(&sl_lock);
  56. #endif
  57. }
  58.  
  59.  
  60. SPINLOCK_INLINE
  61. void
  62. Spinlock::unlock()
  63. {
  64.  
  65.     (void) S_UNLOCK(&sl_lock);
  66. #ifndef NO_PREEMPT
  67.     thisthread->releasingspinlock();
  68. #endif  NO_PREEMPT
  69.  
  70. }
  71.  
  72. SPINLOCK_INLINE
  73. Spinlock::~Spinlock()
  74. {
  75.     //
  76.     // We should abort if the lock is not free. (?) XXX
  77.     // For now just unlock it for backward compatibility.
  78.     //
  79.     if (testlock())
  80.         unlock();
  81.         
  82. }
  83.  
  84.  
  85. #endif DO_SPINLOCK_INLINE || SPINLOCK_C
  86.